#include "udp_client.hpp"
#include <cerrno>
#include <cstring>
#include <iostream>
#include <pthread.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "error.hpp"

void usage(std::string proc)
{
    std::cout << "usage:\n\t" << proc.c_str() << "serverip "
              << "serverport" << std::endl;
}
//未来呢，客户端也是要多线程并发执行的
// 不断的传数据，以及不断的收数据

void* Recv(void* args)
{
    pthread_detach(pthread_self());
    int sock = *(static_cast<int*>(args));

    while(true)
    {
        // 从服务器端接收数据
        struct sockaddr_in tmp;
        socklen_t len = sizeof(tmp);
        memset(&tmp, 0, sizeof(tmp));
        char buf[1024] = {0};
        int n = recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *)&tmp, &len);
        if (n < 0)
            continue;
        buf[n] = 0;
        // std::cout << buf << std::endl;
        std::cout << buf << std::endl; //在命令行中进行重定向体验感更强一点。
    }
}
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        usage(argv[0]);
        exit(USAGE_ERR);
    }

    // 客户端：
    // 只需要创建套接字即可，不需要进行bind，由os自主完成绑定，并构建数据段
    int sock = socket(AF_INET, SOCK_DGRAM, 0);

    std::string serverip = argv[1];
    std::uint16_t serverport = atoi(argv[2]);

    // 填充 struct sockaddr_in
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(serverip.c_str());
    server.sin_port = ntohs(serverport);

    //创建子线程
    pthread_t t;
    pthread_create(&t,nullptr,Recv,(void*)&sock);
    
    // 进行通信
    while (true)
    {
        std:: cerr << "please enter#";
        std::string mess;
        getline(std::cin, mess);
        // 发送数据
        sendto(sock, mess.c_str(), mess.size(), 0, (struct sockaddr *)&server, sizeof(server));
    }

    return 0;
}